<template>
    <div class="button-group1">
        <el-button type="primary" @click="addClue">新增线索</el-button>
        <el-button type="success" @click="importClue">批量导入</el-button>
        <el-button type="danger" @click="delClues">批量删除</el-button>
    </div>

    <el-table :data="cluePageInfo.list" style="width: 100%" @selection-change="selectId">
        <el-table-column type="selection" width="50px"/>
        <el-table-column type="index" label="序号" width="55px"/>
        <el-table-column property="ownerDo.name" label="负责人" width="120"/>
        <el-table-column property="activityDo.name" label="所属活动"/>
        <el-table-column label="姓名">
            <template #default="scope">
                <a href="javascript:void(0)" @click="view(scope.row.id)">{{ scope.row.fullName }}</a>
            </template>
        </el-table-column>
        <el-table-column property="phone" label="手机" width="120"/>
        <el-table-column property="weixin" label="微信" width="120"/>
        <el-table-column property="intentionStateDo.typeValue" label="意向状态"/>
        <el-table-column property="intentionProductDo.name" label="意向产品"/>
        <el-table-column property="stateDo.typeValue" label="线索状态"/>
        <el-table-column property="sourceDo.typeValue" label="线索来源"/>
        <el-table-column property="nextContactTime" label="下次联系时间" width="165"/>
        <el-table-column label="操作" width="230">
            <template #default="scope">
                <el-button type="success" :icon="Message" circle @click="view(scope.row.id)"/>
                <el-button type="primary" :icon="Edit" circle @click="edit(scope.row.id)"/>
                <el-button type="danger" :icon="Delete" circle @click="delClue(scope.row.id)"/>
            </template>
        </el-table-column>
    </el-table>

    <el-pagination
        background layout="prev, pager, next, jumper, total"
        :total="cluePageInfo.total"
        :page-size="cluePageInfo.pageSize"
        @change="toPage"/>

    <!--
        弹窗
        clueDialogVisible控制弹窗是否显示
    -->
    <el-dialog v-model="clueDialogVisible" title="导入线索" width="500px" align-center>
        <!-- 上传组件 -->
        <el-upload
            ref="uploadRef"
            action="http://localhost:8088/api/importExcel"
            method="post"
            name="excelFile"
            :auto-upload="false"
            :headers="header"
            :on-success="uploadSuccess"
            limit="1">
            <template #trigger>
                <el-button type="primary">上传文件</el-button>
            </template>
        </el-upload>

        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="importExcel">导入</el-button>
                <el-button @click="clueDialogVisible = false">取消</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup>
import {inject, onMounted, ref} from 'vue'
import {useRouter, useRoute} from 'vue-router'
import {doDelete, doGet} from "../http/httpRequest.js";
import {confirmMessage, showMessage} from "../util/message.js";
import {Delete, Edit, Message} from "@element-plus/icons-vue";
import {TOKEN} from "../util/constant.js";

// 线索分页信息响应式对象，存储列表数据、总条数、页码等分页相关数据
let cluePageInfo = ref({});
// 路由实例，用于页面导航跳转
let router = useRouter();
// 路由对象，用于获取当前路由信息
let route = useRoute();
// 注入的刷新函数（从父组件或全局注入，用于数据刷新操作）
let flush = inject('flush');
// 上传组件的引用，用于手动触发上传操作
const uploadRef = ref();
// 控制导入线索弹窗显示/隐藏的响应式变量
let clueDialogVisible = ref(false);
let clues = [];
// 上传请求头配置（响应式对象）
// 使用ref包装确保token更新时能实时同步到上传组件
// Authorization格式通常为"Bearer token"，此处根据后端要求直接使用token字符串
let header = ref({
    Authorization: sessionStorage.getItem(TOKEN) // 从本地存储获取认证令牌
})

// 组件挂载完成生命周期钩子
// 在DOM渲染完毕后自动执行初始化操作
onMounted(() => {
    // 加载第一页线索数据，确保页面打开即展示内容
    loadClueList(1); // 调用分页加载函数，初始页码为1
})

// 手动触发文件上传函数
// 与弹窗中的"导入"按钮绑定，实现手动控制上传时机
const importExcel = () => {
    // 通过ref获取上传组件实例，调用其submit方法提交文件
    // 需确保已选择文件，否则submit无效果（可添加前置校验优化）
    uploadRef.value.submit();
}

// 文件上传成功回调函数（Element Plus Upload组件标准回调）
// @param {Object} response - 后端返回的响应数据
// @param {File} uploadFile - 当前上传的文件对象
// @param {Array} uploadFiles - 上传文件列表（因limit=1，此处长度恒为1）
const uploadSuccess = (response, uploadFile, uploadFiles) => {
    // 根据后端约定的状态码判断上传结果
    if (response.code == 200) { // 成功状态码（需与后端保持一致）
        showMessage('导入成功', 'success'); // 显示成功提示
        flush(); // 触发数据刷新，重新加载线索列表
        clueDialogVisible.value = false; // 关闭导入弹窗（补充优化点）
    } else {
        showMessage('导入失败: ' + (response.msg || '未知错误'), 'error'); // 显示失败原因
    }
}

/**
 * 加载线索列表数据
 * @param {number} current - 当前页码
 * 调用API获取分页数据并更新到响应式对象中
 */
const loadClueList = current => {
    // 调用GET请求获取线索分页数据，参数为当前页码
    doGet('api/clues', {
        current: current
    }).then(resp => {
        // 检查响应状态码是否为成功(200)
        if (resp.data.code == 200) {
            // 将获取的分页数据（包含列表、总条数等）赋值给响应式对象
            cluePageInfo.value = resp.data.info;
        } else {
            // 接口调用失败时显示错误消息
            showMessage(resp.data.msg, 'error');
        }
    })
}

/**
 * 分页页码变更处理函数
 * @param {number} current
 * 触发对应页码的列表数据加载
 */
const toPage = current => {
    loadClueList(current);
}

/**
 * 打开导入线索弹窗
 * 将控制弹窗显示的响应式变量设为true
 */
const importClue = () => {
    clueDialogVisible.value = true;
}

/**
 * 查看线索详情
 * @param {number} id - 线索ID
 * 跳转到线索详情页面
 */
const view = id => {
    router.push('/dashboard/clue/' + id);
}

/**
 * 编辑线索
 * @param {number} id - 线索ID
 * 跳转到线索编辑页面
 */
const edit = id => {
    router.push('/dashboard/clue/edit/' + id);
}

/**
 * 单个线索删除函数
 * @param {number} id - 要删除的线索ID
 * 显示确认对话框，用户确认后调用API删除指定线索并刷新列表
 */
const delClue = id => {
    // 显示删除确认对话框，类型为警告(warning)
    confirmMessage('确定删除吗？', 'warning').then(() => {
        // 调用DELETE请求删除指定ID的线索
        doDelete('/api/clue/' + id).then(resp => {
            // 检查响应状态码是否为成功(200)
            if (resp.data.code == 200) {
                // 删除成功：显示成功消息并刷新列表数据
                showMessage(resp.data.msg, 'success');
                flush(); // 触发刷新函数，重新加载线索列表
            } else {
                // 删除失败：显示错误消息
                showMessage(resp.data.msg, 'error');
            }
        })
    })
}

/**
 * 表格选择项变更处理函数
 * @param {Array} item - 选中的表格行数据数组
 * 收集选中行的线索ID，存储到clues数组中（用于批量删除）
 */
const selectId = item => {
    // 清空现有选中ID列表，避免残留旧数据
    clues = [];
    // 遍历选中的行数据，提取每条线索的ID并添加到数组
    for (let index in item) {
        clues.push(item[index].id);
    }
}

/**
 * 批量删除线索函数
 * 检查是否选中线索，确认后调用API批量删除并刷新列表
 */
const delClues = () => {
    // 前置校验：如果未选中任何线索，显示警告提示并终止操作
    if (clues.length == 0) {
        showMessage('请选择要删除的线索', 'warning');
        return;
    } else {
        // 显示批量删除确认对话框，用户确认后执行删除逻辑
        confirmMessage('确定删除吗？', 'warning').then(() => {
            // 数据格式化：将选中的ID数组转换为逗号分隔的字符串（适应后端接口要求）
            let ids = clues.join(',');
            // 调用DELETE请求批量删除线索，参数为格式化后的ID字符串
            doDelete('/api/clues', {
                ids: ids
            }).then(resp => {
                // 检查响应状态码是否为成功(200)
                if (resp.data.code == 200) {
                    // 批量删除成功：显示成功消息并刷新列表数据
                    showMessage(resp.data.msg, 'success');
                    flush(); // 触发刷新函数，重新加载线索列表
                } else {
                    // 批量删除失败：显示错误消息
                    showMessage(resp.data.msg, 'error');
                }
            })
        })
    }
}

/**
 * 新增线索
 * 跳转到线索新增页面
 */
const addClue = () => {
    router.push('/dashboard/clue/add');
}
</script>

<style scoped>
.el-table {
    margin-top: 20px;
}

.button-group1 {
    display: flex;
    justify-content: flex-end;
}

.el-pagination {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
}

.button-container {
    display: flex;
    justify-content: center;
}
</style>